
#ifndef __JJBExtensionConst__H__
#define __JJBExtensionConst__H__

#import <Foundation/Foundation.h>

#ifndef JJB_LOCK
#define JJB_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#endif

#ifndef JJB_UNLOCK
#define JJB_UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif

// 信号量
#define JJBExtensionSemaphoreCreate \
extern dispatch_semaphore_t JJBe_signalSemaphore; \
extern dispatch_once_t JJBe_onceTokenSemaphore; \
dispatch_once(&JJBe_onceTokenSemaphore, ^{ \
    JJBe_signalSemaphore = dispatch_semaphore_create(1); \
});

// 过期
#define JJBExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)

// 构建错误
#define JJBExtensionBuildError(clazz, msg) \
NSError *error = [NSError errorWithDomain:msg code:250 userInfo:nil]; \
[clazz setJJB_error:error];

// 日志输出
#ifdef DEBUG
#define JJBExtensionLog(...) NSLog(__VA_ARGS__)
#else
#define JJBExtensionLog(...)
#endif

/**
 * 断言
 * @param condition   条件
 * @param returnValue 返回值
 */
#define JJBExtensionAssertError(condition, returnValue, clazz, msg) \
[clazz setJJB_error:nil]; \
if ((condition) == NO) { \
    JJBExtensionBuildError(clazz, msg); \
    return returnValue;\
}

#define JJBExtensionAssert2(condition, returnValue) \
if ((condition) == NO) return returnValue;

/**
 * 断言
 * @param condition   条件
 */
#define JJBExtensionAssert(condition) JJBExtensionAssert2(condition, )

/**
 * 断言
 * @param param         参数
 * @param returnValue   返回值
 */
#define JJBExtensionAssertParamNotNil2(param, returnValue) \
JJBExtensionAssert2((param) != nil, returnValue)

/**
 * 断言
 * @param param   参数
 */
#define JJBExtensionAssertParamNotNil(param) JJBExtensionAssertParamNotNil2(param, )

/**
 * 打印所有的属性
 */
#define JJBLogAllIvars \
- (NSString *)description \
{ \
    return [self JJB_keyValues].description; \
}
#define JJBExtensionLogAllProperties JJBLogAllIvars

/** 仅在 Debugger 展示所有的属性 */
#define JJBImplementDebugDescription \
- (NSString *)debugDescription \
{ \
return [self JJB_keyValues].debugDescription; \
}

/**
 *  类型（属性类型）
 */
FOUNDATION_EXPORT NSString *const JJBPropertyTypeInt;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeShort;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeFloat;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeDouble;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeLong;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeLongLong;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeChar;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeBOOL1;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeBOOL2;
FOUNDATION_EXPORT NSString *const JJBPropertyTypePointer;

FOUNDATION_EXPORT NSString *const JJBPropertyTypeIvar;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeMethod;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeBlock;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeClass;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeSEL;
FOUNDATION_EXPORT NSString *const JJBPropertyTypeId;

#endif
